//@author A0101200R

package testcases;

import static org.junit.Assert.assertEquals;
import logic.ScheduleHelp;

import org.junit.Test;

public class ScheduleHelpTest {

	ScheduleHelp helpCommand = new ScheduleHelp();

	// list of constants
	private static final String NEW_LINE = "\n";
	private static final String EMPTY_STRING = "";
	private static final String WRONG_INPUT = "incorrect";

	// list of direct help commands
	private static final String ADD = "add";
	private static final String DELETE = "delete";
	private static final String MODIFY = "modify";
	private static final String UNDO = "undo";
	private static final String REDO = "redo";
	private static final String SEARCH = "search";
	private static final String SORT = "sort";
	private static final String DISPLAY = "display";
	private static final String MARK = "mark";

	// list of messages
	private static final String MSG_ADD = "Add Commands:" + NEW_LINE;
	private static final String MSG_DELETE = "Delete Command:" + NEW_LINE;
	private static final String MSG_MODIFY = "Modify Command:" + NEW_LINE;
	private static final String MSG_UNDO = "Undo Command:" + NEW_LINE;
	private static final String MSG_REDO = "Redo Command:" + NEW_LINE;
	private static final String MSG_SEARCH = "Search Commands:" + NEW_LINE;
	private static final String MSG_SORT = "Sort Commands:" + NEW_LINE;
	private static final String MSG_DISPLAY = "Display Commands:" + NEW_LINE;
	private static final String MSG_MARK = "Mark Commands:" + NEW_LINE;
	private static final String MSG_HElP = "Help Command:" + NEW_LINE;

	// list of error messages
	private static final String ERROR_WRONG_INPUT = "Error! The input after help is wrong.";

	// list of add commands
	private static final String COMMAND_ADD_TIMED = "add {taskName} on {ddmmyyyy} from {startTime} to {endTime}";
	private static final String COMMAND_ADD_DATELINE1 = "add {taskName} on {ddmmyyyy} by {endTime}";
	private static final String COMMAND_ADD_DATELINE2 = "add {taskName} on {ddmmyyyy}";
	private static final String COMMAND_ADD_FLOATING = "add {taskName}";
	private static final String COMMAND_ADD_ALTERNATIVE = "NOTE: {ddmmyyyy} can be replaced by" + NEW_LINE 
														+ "eg  {today} or {monday} or {21 apr} or {21 apr 2014}";

	// list of delete command
	private static final String COMMAND_DELETE = "delete {taskNumber}";

	// list of modify command
	private static final String COMMAND_MODIFY = "modify {taskNumber} n {newEventName} d {newEventDate} st {newEventStartTime} et {newEventEndTime}";
	private static final String COMMAND_MODIFY_DETAILS = " n : taskName, d : taskDate, st : startTime, et: endTime ";
	private static final String COMMAND_MODIFY_NOTE = "NOTE: You can choose to modify 1-4 parameters.";

	// list of undo command
	private static final String COMMAND_UNDO = "undo";

	// list of redo command
	private static final String COMMAND_REDO = "redo";

	// list of search commands
	private static final String COMMAND_SEARCH_KEYWORD = "search {keyword}";
	private static final String COMMAND_SEARCH_DATE = "search {ddmmyyyy}";
	private static final String COMMAND_SEARCH_DATERANGE = "search {ddmmyyyy ddmmyyyy}";
	private static final String COMMAND_SEARCH_TYPE = "search {timed} or search {deadline} or search {floating}";

	// list of sort commands
	private static final String COMMAND_SORT_ALPHABETICAL = "search -sa or display -sa (alphabetical order)";
	private static final String COMMAND_SORT_URGENCY = "search -su or display -su (urgency)";
	private static final String COMMAND_SORT_TYPE = "search -st or display -st (type)";

	// list of display commands
	private static final String COMMAND_DISPLAY_TODAY = "display (tasks on the day itself)";
	private static final String COMMAND_DISPLAY_ALL = "display all";
	private static final String COMMAND_DISPLAY_DONE = "display done";
	private static final String COMMAND_DISPLAY_UNDONE = "display undone";
	private static final String COMMAND_DISPLAY_INDEX = "display {index} (show details of the particular task)";
	private static final String COMMAND_DISPLAY_NOTE = "NOTE: if there is more than 5 tasks available, only the name will be shown.";

	// list of mark command
	private static final String COMMAND_MARK_DONE = "mark {keyword} done";
	private static final String COMMAND_MARK_UNDONE = "mark {keyword} undone";

	// help command
	private static final String COMMAND_HELP_GENERAL = "help";
	private static final String COMMAND_HELP_SPECIFIC = "help {command}";

	private String outputAdd() {
		String output = MSG_ADD 
				+ COMMAND_ADD_TIMED + NEW_LINE
				+ COMMAND_ADD_DATELINE1 + NEW_LINE 
				+ COMMAND_ADD_DATELINE2 + NEW_LINE 
				+ COMMAND_ADD_FLOATING + NEW_LINE
				+ COMMAND_ADD_ALTERNATIVE + NEW_LINE;

		return output;
	}

	private String outputDelete() {
		String output = MSG_DELETE 
				+ COMMAND_DELETE + NEW_LINE;

		return output;
	}

	private String outputModify() {
		String output = MSG_MODIFY 
				+ COMMAND_MODIFY + NEW_LINE
				+ COMMAND_MODIFY_DETAILS + NEW_LINE 
				+ COMMAND_MODIFY_NOTE + NEW_LINE;

		return output;
	}

	private String outputUndo() {
		String output = MSG_UNDO + COMMAND_UNDO + NEW_LINE;

		return output;
	}

	private String outputRedo() {
		String output = MSG_REDO + COMMAND_REDO + NEW_LINE;

		return output;
	}

	private String outputSearch() {
		String output = MSG_SEARCH 
				+ COMMAND_SEARCH_KEYWORD + NEW_LINE
				+ COMMAND_SEARCH_DATE + NEW_LINE 
				+ COMMAND_SEARCH_DATERANGE + NEW_LINE 
				+ COMMAND_SEARCH_TYPE + NEW_LINE;

		return output;
	}

	private String outputSort() {
		String output = MSG_SORT 
				+ COMMAND_SORT_ALPHABETICAL + NEW_LINE
				+ COMMAND_SORT_URGENCY + NEW_LINE 
				+ COMMAND_SORT_TYPE + NEW_LINE;

		return output;
	}

	private String outputDisplay() {
		String output = MSG_DISPLAY 
				+ COMMAND_DISPLAY_TODAY + NEW_LINE
				+ COMMAND_DISPLAY_ALL + NEW_LINE 
				+ COMMAND_DISPLAY_DONE + NEW_LINE 
				+ COMMAND_DISPLAY_UNDONE + NEW_LINE
				+ COMMAND_DISPLAY_INDEX + NEW_LINE 
				+ COMMAND_DISPLAY_NOTE + NEW_LINE;

		return output;
	}

	private String outputMark() {
		String output = MSG_MARK 
				+ COMMAND_MARK_DONE + NEW_LINE
				+ COMMAND_MARK_UNDONE + NEW_LINE;

		return output;
	}

	private String outputHelp() {
		String output = MSG_HElP 
				+ COMMAND_HELP_GENERAL + NEW_LINE
				+ COMMAND_HELP_SPECIFIC + NEW_LINE;

		return output;
	}

	private String output(String userCommandInput) {
		String lineToOutput;

		String output = outputAdd() + NEW_LINE 
					+ outputDelete() + NEW_LINE
					+ outputModify() + NEW_LINE 
					+ outputUndo() + NEW_LINE
					+ outputRedo() + NEW_LINE 
					+ outputSearch() + NEW_LINE
					+ outputSort() + NEW_LINE 
					+ outputDisplay() + NEW_LINE
					+ outputMark() + NEW_LINE 
					+ outputHelp();

		switch (userCommandInput) {

		case EMPTY_STRING:
			lineToOutput = output;
			break;
		case ADD:
			lineToOutput = outputAdd().trim();
			break;
		case DELETE:
			lineToOutput = outputDelete().trim();
			break;
		case MODIFY:
			lineToOutput = outputModify().trim();
			break;
		case UNDO:
			lineToOutput = outputUndo().trim();
			break;
		case REDO:
			lineToOutput = outputRedo().trim();
			break;
		case SEARCH:
			lineToOutput = outputSearch().trim();
			break;
		case SORT:
			lineToOutput = outputSort().trim();
			break;
		case DISPLAY:
			lineToOutput = outputDisplay().trim();
			break;
		case MARK:
			lineToOutput = outputMark().trim();
			break;
		default:
			lineToOutput = ERROR_WRONG_INPUT;
		}

		return lineToOutput;

	}

	@Test
	public void testHelp() {
		String expected;

		expected = output(EMPTY_STRING);
		assertEquals(expected, helpCommand.helpList(EMPTY_STRING));

		expected = output(ADD);
		assertEquals(expected, helpCommand.helpList(ADD));

		expected = output(DELETE);
		assertEquals(expected, helpCommand.helpList(DELETE));

		expected = output(MODIFY);
		assertEquals(expected, helpCommand.helpList(MODIFY));

		expected = output(UNDO);
		assertEquals(expected, helpCommand.helpList(UNDO));

		expected = output(REDO);
		assertEquals(expected, helpCommand.helpList(REDO));

		expected = output(SEARCH);
		assertEquals(expected, helpCommand.helpList(SEARCH));

		expected = output(SORT);
		assertEquals(expected, helpCommand.helpList(SORT));

		expected = output(DISPLAY);
		assertEquals(expected, helpCommand.helpList(DISPLAY));

		expected = output(MARK);
		assertEquals(expected, helpCommand.helpList(MARK));

		expected = output(WRONG_INPUT);
		assertEquals(expected, helpCommand.helpList(WRONG_INPUT));

	}

}
